package com.powerfl.frm.taf{
	
	import away3d.animators.*;
	import away3d.core.geom.*;
	import away3d.core.math.*;
	
	import flash.geom.*;
	import flash.utils.*;
	
	final internal class TAFtween{
		
		include 'tween/tweenEase.as';
		include 'tween/tweenAPI.as';
		
		private var _object:*;
		private var _id:String;
		
		private var _timeline:Array;
		
		private var _tweens:Vector.<TAFtweenVar> = new Vector.<TAFtweenVar>();
		private var _len:int;
		
		private var _cursor:int = -1;
		
		private var _ease:Function;
		private var _startTime:int;
		private var _time:Number;
		private var _delay:Number;
		private var _pauseTime:int;
		private var _end:Array;
		private var _loop:int;
		
		private var _update:Array;
		private var _isUpdate:int;
		private var _updateLen:int;
		
		
		private var _init:*;
		private var _length:*;
		private var _isVar:int;
		
		
		
		public function TAFtween(){}
		private function collectVar():void{
			if( _init is TAFawayVar ){
				TAF.SELF.poolCollectAwayVar( _init );
			}
			if( _length is TAFawayVar ){
				TAF.SELF.poolCollectAwayVar( _length );
			}
			_init = null;
			_length = null;	
		}
		private function collect():TAFtween{
			var i:int, j:int;
			collectVar();
			_tweens.length = 0;
			_cursor = -1;
			_isUpdate = _len = _delay = _pauseTime = _loop = _isVar = 0;
			_update = null;
			_end = null;
			_ease = null;
			_timeline = null;
			_object = null;
			return this;
		}
		private function init( $isLoop:int = 0 ):int{
			var key:*, curr:TAFtweenVar;
			if( ++_cursor < _len ){
				curr = _tweens[_cursor];
				if( _timeline ){
					_time = _timeline[_cursor].time;
					if( _timeline[_cursor].ease ){
						_ease = _timeline[_cursor].ease;
					}else if( curr.ease is Function ){
						_ease = curr.ease;
					}
				}else{
					_time = curr.time;
					_ease = curr.ease;
				}
				_end = curr.end;
				_update = curr.update;
				if( _update ){
					_isUpdate = -1;
					_updateLen = _update.length;
				}else{
					_isUpdate = 0;
				}
				if( $isLoop < 0 ){
					if( _timeline ){
						_delay = _timeline[_cursor].delay;
					}else{
						_delay = curr.loopDelay;
					}
					if( curr.yoyo < 0 ){
						if( _length is TAFawayVar ){
							if( ( curr.loop - _loop )%2 ){
								_init.initFromVar( null, _length, '+' );
							}else if( _loop < curr.loop ){
								_init.initFromVar( null, _length, '-' );
							}
							_length.initFromVar( null, -1, '*' );
						}else{
							for( key in _init ){
								if( ( curr.loop - _loop )%2 ){
									_init[key] += _length[key];
								}else if( _loop < curr.loop ){
									_init[key] -= _length[key];
								}
								_length[key] *= -1;
							}
						}
					}
				}else{
					if( _timeline ){
						_loop = 0;
						_delay = _timeline[_cursor].delay;
					}else{
						_loop = curr.loop;
						_delay = curr.delay;
					}
					_isVar = 0;
					if( curr.to is TAFawayVar ){
						_isVar = -1;
						curr.to.delay( _object );
						_init = TAF.SELF.poolPullAwayVar().initFromVar( curr.to, _object );
					}else if( curr.to ){
						_init = {};
						for( key in curr.to ){
							_init[key] = _object[key];
						}
					}
					
					if( _isVar < 0 ){
						_length = TAF.SELF.poolPullAwayVar().initFromVar( curr.to, _init, '-' ); 
						_length.init = _init;
						_length.ease = _ease;
						_length.object = _object;		
					}else if( _init ){
						_length = {};
						for( key in curr.to ){
							_length[key] = curr.to[key] - _init[key];
						}
					}
				}
				_startTime = TAF.TIME + _delay;
				_pauseTime = -1;
				return 0;
			}else{
				return -1;
			}
		}
		private function end():void{
			var key:*;
			if( _isVar < 0 ){
				if( _length ){
					_length.applyTween( 1 );
				}
				if( _loop === 0 ){
					collectVar();
				}
			}else if( _init ){
				for( key in _length ){
					_object[key] = _init[key] + _length[key];
				}
			}
		}
		private function pause():void{
			if( _pauseTime < 0 ){
				_pauseTime = TAF.TIME;
			}
		}
		private function resume():void{
			var t:int;
			if( _pauseTime > 0 ){
				t = TAF.TIME - _pauseTime;
				_startTime += t;
				_pauseTime = -1;
			}
		}
		private function ease():int{
			var key:*, rate:Number, i:int, j:int, k:int, l:int, endParam:Array;
			if( _pauseTime < 0 ){
				rate = ( TAF.TIME - _startTime ) * _time;
				if( rate < 0 ){ //delay대기
					return 0;
				}else if( rate < 1 ){
					if( _isVar < 0 ){
						_length.applyTween( rate );
					}else if( _init ){
						for( key in _length ){
							_object[key] = _ease( _init[key], _length[key], rate );
						}
					}
					if( _isUpdate < 0 ){
						for( i = 0 ; i < _updateLen ; i += 2 ){
							_update[i].apply( null, _update[i+1] );
						}
					}
					return 0;
				}else{
					end();
					if( _loop ){
						--_loop;
						--_cursor;
						return init( -1 );
					}else{
						if( _end ){
							for( i = 0 , j = _end.length ; i < j ; ++i ){
								if( _end[i] is Array ){
									if( _end[i][0] is String ){
										_end[i][0] = TAF.SELF.flowGet( _end[i][0] );
									}
									if( _end[i].length > 1 ){
										_end[i][0].apply( null, _end[i].slice(1) );
									}else{
										_end[i][0]();
									}
								}else if( _end[i] is String ){
									_end[i] = TAF.SELF.flowGet( _end[i] );
									_end[i]();
								}else if( _end[i] is Function ){
									_end[i]();
								}else if( _end[i] is Number ){
									_cursor = _end[i] - 1;
									return init();
								}
							}
						}
						return init();
					}
				}
			}else{
				return 0;
			}
		}
	}
}
class tweenObject{
	internal var RA:Array = [];
	internal var RD:Array = [];
	internal var RF:Array = [];
	internal var LA:Array = [];
	internal var LD:Array = [];
	internal var LF:Array = [];
	public function tweenObject(){}
	internal function clear():void{
		RA.length = 0;
		RD.length = 0;
		RF.length = 0;
		LA.length = 0;
		LD.length = 0;
		LF.length = 0;
	}
}